Skip to main content

Timeout and Abort in the .NET Engine

This article explains how to use timeout and abort for report cancellation in the embedded .NET Engine.

Overview

The .NET API exposes per-report cancellation controls:

  • Report.Timeout (seconds)
  • Report.Abort()

These are instance-scoped. If many reports run concurrently, setting timeout or abort on one report instance does not stop other reports.

Timeout Behavior

Use Report.Timeout to set a runtime limit.

  • 0 means no timeout.
  • Timeout throws net.windward.xmlreport.TimeoutException with mode TIMEOUT.

Precedence and Call Order

Timeout is honored regardless of whether it is set before or after ProcessSetup().

Order of precedence:

  1. Report.Timeout
  2. report.timeout configuration property

If both are set, Report.Timeout wins.

Abort Behavior

Use Report.Abort() to cancel a running report from another thread.

  • Abort() signals cancellation and returns immediately.
  • The running report exits at the next checkpoint.
  • Abort throws net.windward.xmlreport.TimeoutException with mode ABORT.

Bounded Observation

Timeout and abort are checked across long-running phases such as data processing, parsing, layout, chart handling, and output building.

Cancellation is cooperative and checkpoint-based rather than forceful thread termination.

.NET Usage Example

using System;
using System.Collections.Generic;
using System.IO;
using System.Threading;
using net.windward.api.csharp;
using WindwardInterfaces.net.windward.api.csharp;

public class DotNetTimeoutAbortExample
{
public static void Main()
{
Report.Init();

using (var template = File.OpenRead("template.docx"))
using (var output = File.Open("report.pdf", FileMode.Create))
{
Report report = new ReportPdf(template, output);

// API timeout has highest precedence over report.timeout config property.
report.Timeout = 30;

report.ProcessSetup();

var providers = new Dictionary<string, IReportDataSource>();
// providers.Add("", yourDatasource);

var abortThread = new Thread(() =>
{
Thread.Sleep(5000);
report.Abort();
});
abortThread.IsBackground = true;
abortThread.Start();

try
{
report.ProcessData(providers);
report.ProcessComplete();
}
catch (net.windward.xmlreport.TimeoutException ex)
{
if (ex.getMode() == net.windward.xmlreport.TimeoutException.TIMEOUT)
{
Console.WriteLine("Report timed out");
}
else if (ex.getMode() == net.windward.xmlreport.TimeoutException.ABORT)
{
Console.WriteLine("Report aborted");
}
throw;
}
}
}
}

Logging and Diagnostics

The engine logs timeout and abort observations to help identify where cancellation was requested and where it was observed.

Best Practices

  • Prefer Report.Abort() and Report.Timeout over Thread.Abort().
  • Do not share one report instance across multiple unrelated jobs.
  • Catch timeout exceptions and distinguish TIMEOUT from ABORT.
  • Keep resource cleanup in finally blocks for output streams and data connections.